namespace Xsxiaosa.Net
{
    using System;
    using System.IO;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public class FtpWebRequest : WebRequest
    {
        // Events
        public event FtpCommandSentEventHandler CommandSent;
        public event FtpResponseReadEventHandler ResponseRead;
        public event FtpStateChangedEventHandler StateChanged;
        public event FtpTransferProgressEventHandler TransferProgress;

        // Methods
        static FtpWebRequest()
        {
            FtpWebRequest._creator = new WebRequestCreator();
        }

        internal FtpWebRequest(Uri uri)
        {
            this._proxy = new FtpProxy();
            this._ftp = null;
            this._asyncResult = null;
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }
            this._contentType = null;
            this._credentials = null;
            this._headers = new WebHeaderCollection();
            this._method = Xsxiaosa.Net.FtpWebRequest.FtpMethod.RETR;
            this._uri = uri;
            this._timeout = 60000;
        }

        public override void Abort()
        {
            Ftp ftp1 = null;
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if (this._asyncResult == null)
                {
                    return;
                }
                if (this._ftp == null)
                {
                    return;
                }
                ftp1 = this._ftp;
                this._ftp = null;
            }
            ftp1.Abort();
        }

        public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
        {
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if ((this._asyncResult != null) || (this._ftp != null))
                {
                    throw new InvalidOperationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationPending"));
                }
                if (this._method == Xsxiaosa.Net.FtpWebRequest.FtpMethod.STOR)
                {
                    goto Label_005E;
                }
                throw new ProtocolViolationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestInvalidVerbForUpload"));
            }
        Label_005E:
            this._asyncResult = new XsxiaosaAsyncResult(this, "GetRequestStream", callback, state, new object[0]);
            this._asyncResult.Thread.Start();
            return this._asyncResult;
        }

        public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
        {
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if ((this._asyncResult != null) || (this._ftp != null))
                {
                    throw new InvalidOperationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationPending"));
                }
                if (this._method == Xsxiaosa.Net.FtpWebRequest.FtpMethod.STOR)
                {
                    goto Label_005E;
                }
                throw new ProtocolViolationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestInvalidVerbForUpload"));
            }
        Label_005E:
            this._asyncResult = new XsxiaosaAsyncResult(this, "GetResponse", callback, state, new object[0]);
            this._asyncResult.Thread.Start();
            return this._asyncResult;
        }

        private void CheckState()
        {
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if (this._asyncResult == null)
                {
                    return;
                }
                throw new InvalidOperationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestOperationPending"));
            }
        }

        private void ConnectAndLogin()
        {
            string text1;
            string text2;
            if (this._asyncResult == null)
            {
                this._ftp.Timeout = this.Timeout;
            }
            if ((this._proxy as FtpProxy) != null)
            {
                this._ftp.Proxy = ((FtpProxy) this._proxy);
            }
            this._ftp.Connect(this._uri.Host, this._uri.Port);
            if (this._credentials == null)
            {
                text1 = "anonymous";
                text2 = "guest";
            }
            else
            {
                text1 = this._credentials.UserName;
                text2 = this._credentials.Password;
            }
            this._ftp.Login(text1, text2);
            this._ftp.SetTransferType(FtpTransferType.Binary);
        }

        public override Stream EndGetRequestStream(IAsyncResult asyncResult)
        {
            object[] objArray1;
            XsxiaosaAsyncResult result1 = (asyncResult as XsxiaosaAsyncResult);
            if ((result1 == null) || (this._asyncResult != result1))
            {
                objArray1 = new object[1];
                objArray1[0] = "GetRequestStream";
                throw new ArgumentException(Xsxiaosa.Net.Messages.GetString("InvalidEndCall", objArray1));
            }
            object obj1 = result1.Finish(this, "GetRequestStream");
            FtpWebRequest request1 = this;
            lock (request1)
            {
                this._asyncResult = null;
                this._ftp = null;
            }
            Exception exception1 = (obj1 as Exception);
            if (exception1 != null)
            {
                if ((exception1 as ThreadAbortException) != null)
                {
                    throw new WebException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationAborted"), exception1, WebExceptionStatus.RequestCanceled, null);
                }
                if ((exception1 as FtpException) != null)
                {
                    throw ((FtpException) exception1).ToWebException();
                }
                throw new WebException(Xsxiaosa.Net.Messages.GetString("AsyncCallException"), exception1, WebExceptionStatus.RequestCanceled, null);
            }
            return ((FtpWebStream) obj1);
        }

        public override WebResponse EndGetResponse(IAsyncResult asyncResult)
        {
            object[] objArray1;
            XsxiaosaAsyncResult result1 = (asyncResult as XsxiaosaAsyncResult);
            if ((result1 == null) || (this._asyncResult != result1))
            {
                objArray1 = new object[1];
                objArray1[0] = "GetRequestStream";
                throw new ArgumentException(Xsxiaosa.Net.Messages.GetString("InvalidEndCall", objArray1));
            }
            object obj1 = result1.Finish(this, "GetResponse");
            FtpWebRequest request1 = this;
            lock (request1)
            {
                this._asyncResult = null;
                this._ftp = null;
            }
            Exception exception1 = (obj1 as Exception);
            if (exception1 != null)
            {
                if ((exception1 as ThreadAbortException) != null)
                {
                    throw new WebException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationAborted"), exception1, WebExceptionStatus.RequestCanceled, null);
                }
                if ((exception1 as FtpException) != null)
                {
                    throw ((FtpException) exception1).ToWebException();
                }
                throw new WebException(Xsxiaosa.Net.Messages.GetString("AsyncCallException"), exception1, WebExceptionStatus.RequestCanceled, null);
            }
            return ((FtpWebResponse) obj1);
        }

        public override Stream GetRequestStream()
        {
//jyj modify            Stream stream2;
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if (this._ftp != null)
                {
                    throw new InvalidOperationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationPending"));
                }
                if (this._method != Xsxiaosa.Net.FtpWebRequest.FtpMethod.STOR)
                {
                    throw new ProtocolViolationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestInvalidVerbForUpload"));
                }
                this._ftp = new Ftp();
                this._ftp.ResponseRead += new FtpResponseReadEventHandler(this.OnResponseRead);
                this._ftp.CommandSent += new FtpCommandSentEventHandler(this.OnCommandSent);
                this._ftp.TransferProgress += new FtpTransferProgressEventHandler(this.OnTransferProgress);
                this._ftp.StateChanged += new FtpStateChangedEventHandler(this.OnStateChanged);
            }
            Stream stream1 = null;
            try
            {
                this.ConnectAndLogin();
                stream1 = new FtpUploadStream(this._ftp, true, this._uri.PathAndQuery);
                return new FtpWebStream(stream1);
            }
            catch (FtpException exception1)
            {
                throw exception1.ToWebException();
            }
            catch (Exception exception2)
            {
                throw new WebException(exception2.Message, exception2, WebExceptionStatus.ConnectFailure, null);
            }
            finally
            {
                if (stream1 == null)
                {
                    request1 = this;
                    lock (request1)
                    {
                        if (this._ftp != null)
                        {
                            this._ftp.Dispose();
                            this._ftp = null;
                        }
                    }
                }
            }
//jyj modify            return stream2;
        }

        public override WebResponse GetResponse()
        {
//jyj modify            WebResponse response1;
            FtpWebRequest request1 = this;
            lock (request1)
            {
                if (this._ftp != null)
                {
                    throw new InvalidOperationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "OperationPending"));
                }
                if (this._method != Xsxiaosa.Net.FtpWebRequest.FtpMethod.RETR)
                {
                    throw new ProtocolViolationException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestInvalidVerbForUpload"));
                }
                this._ftp = new Ftp();
                this._ftp.ResponseRead += new FtpResponseReadEventHandler(this.OnResponseRead);
                this._ftp.CommandSent += new FtpCommandSentEventHandler(this.OnCommandSent);
                this._ftp.TransferProgress += new FtpTransferProgressEventHandler(this.OnTransferProgress);
                this._ftp.StateChanged += new FtpStateChangedEventHandler(this.OnStateChanged);
            }
            Stream stream1 = null;
            try
            {
                this.ConnectAndLogin();
                stream1 = new FtpDownloadStream(this._ftp, true, this._uri.PathAndQuery);
                return new FtpWebResponse(new FtpWebStream(stream1), this._uri);
            }
            catch (FtpException exception1)
            {
                throw exception1.ToWebException();
            }
            catch (Exception exception2)
            {
                throw new WebException(exception2.Message, exception2, WebExceptionStatus.ConnectFailure, null);
            }
            finally
            {
                if (stream1 == null)
                {
                    request1 = this;
                    lock (request1)
                    {
                        if (this._ftp != null)
                        {
                            this._ftp.Dispose();
                            this._ftp = null;
                        }
                    }
                }
            }
//jyj modify            return response1;
        }

        private void OnCommandSent(object sender, FtpCommandSentEventArgs e)
        {
            if (this.CommandSent != null)
            {
//jyj modify                this.CommandSent.Invoke(this, e);
				this.CommandSent(this, e);
            }
        }

        private void OnResponseRead(object sender, FtpResponseReadEventArgs e)
        {
            if (this.ResponseRead != null)
            {
//jyj modify                this.ResponseRead.Invoke(this, e);
				this.ResponseRead(this, e);
            }
        }

        private void OnStateChanged(object sender, FtpStateChangedEventArgs e)
        {
            if (this.StateChanged != null)
            {
//jyj modify                this.StateChanged.Invoke(this, e);
            this.StateChanged(this, e);
			}
        }

        private void OnTransferProgress(object sender, FtpTransferProgressEventArgs e)
        {
            if (this.TransferProgress != null)
            {
//jyj modify                this.TransferProgress.Invoke(this, e);
				this.TransferProgress(this, e);
            }
        }


        // Properties
        public override long ContentLength
        {
            get
            {
                object[] objArray1 = new object[1];
                objArray1[0] = "ContentLength";
                throw new NotSupportedException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestNotSupported", objArray1));
            }
            set
            {
                object[] objArray1 = new object[1];
                objArray1[0] = "ContentLength";
                throw new NotSupportedException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestNotSupported", objArray1));
            }
        }

        public override string ContentType
        {
            get
            {
                return this._contentType;
            }
            set
            {
                this._contentType = value;
            }
        }

        public static IWebRequestCreate Creator
        {
            get
            {
                return FtpWebRequest._creator;
            }
        }

        public override ICredentials Credentials
        {
            get
            {
                return this._credentials;
            }
            set
            {
                FtpWebRequest request1 = this;
                lock (request1)
                {
                    if ((value != null) && ((value as NetworkCredential) == null))
                    {
                        throw new NotSupportedException(Xsxiaosa.Net.Messages.GetString("ArgumentUnsupportedCredential"));
                    }
                    this.CheckState();
                    this._credentials = ((NetworkCredential) value);
                }
            }
        }

        public override WebHeaderCollection Headers
        {
            get
            {
                return this._headers;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                FtpWebRequest request1 = this;
                lock (request1)
                {
                    this.CheckState();
                    this._headers = value;
                }
            }
        }

        public override string Method
        {
            get
            {
                return this._method.ToString().ToUpper();
            }
            set
            {
                string text1;
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                FtpWebRequest request1 = this;
                lock (request1)
                {
                    this.CheckState();
                    text1 = value.ToUpper();
                    if (text1 == null)
                    {
                        goto Label_0089;
                    }
                    text1 = string.IsInterned(text1);
                    if (text1 != "GET")
                    {
                        if (text1 == "RETR")
                        {
                            goto Label_006E;
                        }
                        if (text1 == "PUT")
                        {
                            goto Label_0077;
                        }
                        if (text1 == "STOR")
                        {
                            goto Label_0080;
                        }
                        goto Label_0089;
                    }
                    this._method = Xsxiaosa.Net.FtpWebRequest.FtpMethod.RETR;
                    return;
                Label_006E:
                    this._method = Xsxiaosa.Net.FtpWebRequest.FtpMethod.RETR;
                    return;
                Label_0077:
                    this._method = Xsxiaosa.Net.FtpWebRequest.FtpMethod.STOR;
                    return;
                Label_0080:
                    this._method = Xsxiaosa.Net.FtpWebRequest.FtpMethod.STOR;
                    return;
                Label_0089:
                    throw new ArgumentException(Xsxiaosa.Net.Messages.GetString(typeof(FtpStrings), "WebRequestInvalidMethod"), value);
                }
            }
        }

        public override bool PreAuthenticate
        {
            get
            {
                return false;
            }
            set
            {
            }
        }

        public override IWebProxy Proxy
        {
            get
            {
                return this._proxy;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                this._proxy = value;
            }
        }

        public override Uri RequestUri
        {
            get
            {
                return this._uri;
            }
        }

        public override int Timeout
        {
            get
            {
                return this._timeout;
            }
            set
            {
                if (value < -1)
                {
                    throw new ArgumentOutOfRangeException("value");
                }
                if (value < 1)
                {
                    value = -1;
                }
                else if (value < 1000)
                {
                    value = 1000;
                }
                this._timeout = value;
            }
        }


        // Fields
        private XsxiaosaAsyncResult _asyncResult;
        private string _contentType;
        private static IWebRequestCreate _creator;
        private NetworkCredential _credentials;
        private Ftp _ftp;
        private WebHeaderCollection _headers;
        private Xsxiaosa.Net.FtpWebRequest.FtpMethod _method;
        private IWebProxy _proxy;
        private int _timeout;
        private Uri _uri;

        // Nested Types
        private enum FtpMethod
        {
            // Fields
            RETR = 0,
            STOR = 1
        }

        private class WebRequestCreator : IWebRequestCreate
        {
            // Methods
            public WebRequestCreator()
            {
            }

            public WebRequest Create(Uri uri)
            {
                return new FtpWebRequest(uri);
            }

        }
    }}

